Optional Chaining
Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
Optional Chaining as an Alternative to Forced Unwrapping
A property that normally returns an Int will return an Int?
when accessed through optional chaining.
1 | class Person { |
Defining Model Classes for Optional Chaining
1 | class Person { |
Accessing Properties Through Optional Chaining
the attempt to set the address property of john.residence
will fail, because john.residence
is currently nil
.
1 | let john = Person() |
The function prints “Function was called” before returning a value, which lets you see whether the right hand side of the = operator was evaluated.
1 | func createAddress() -> Address { |
Calling Methods Through Optional Chaining
functions and methods with no return type have an implicit return type of Void
1 | func printNumberOfRooms() { |
- If you call this method on an optional value with optional chaining, the method’s return type will be
Void?
, notVoid
, because return values are always of an optional type when called through optional chaining - Compare the return value from the printNumberOfRooms call against nil to see if the method call was successful
1 | if john.residence?.printNumberOfRooms() != nil { |
Any attempt to set a property through optional chaining returns a value of type Void?
, which enables you to compare against nil
to see if the property was set successfully
1 | if (john.residence?.address = someAddress) != nil { |
Accessing Subscripts Through Optional Chaining
The optional chaining question mark always follows immediately after the part of the expression that is optional
1 | if let firstRoomName = john.residence?[0].name { |
Similarly, you can try to set a new value through a subscript with optional chaining:
1 | john.residence?[0] = Room(name: "Bathroom") |
Now , it is ok
1 | let johnsHouse = Residence() |
Accessing Subscripts of Optional Type
1 | var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]] |
Linking Multiple Levels of Chaining
- If you try to retrieve an Int value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
- Similarly, if you try to retrieve an Int? value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
1 | if let johnsStreet = john.residence?.address?.street { |
Now, it is ok
1 | let johnsAddress = Address() |
Chaining on Methods with Optional Return Values
1 | if let buildingIdentifier = john.residence?.address?.buildingIdentifier() { |
the optional value you are chaining on is the buildingIdentifier()
method’s return value, and not the buildingIdentifier()
method itself.
1 | if let beginsWithThe = |